package com.cakebackoffice.Model;


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import com.cakebackoffice.database.ClientTable;
import com.cakebackoffice.database.Client_has_Order;
import com.cakebackoffice.database.DataSource;
import com.cakebackoffice.database.IDatabasable;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Client implements IDatabasable {
    private Long idDB;
    private Long remoteID;
    private String name;
    private String firstName;
    private Gender sex = Gender.MALE;
    private Date birthdate;
    private Date subscriptionDate;
    private String photo = null; //drawable ?
    private String deviceID;
    private String phoneNumber;
    private Place latestKnownPosition;
    private Place livingPlace;

    public Client(com.cakebackoffice.clientsoap.contract.Client client) {
        this.remoteID = Long.valueOf(client.id);
        this.name = client.name;
        this.firstName = client.firstname;
        this.deviceID = client.deviceID;
        this.phoneNumber = client.phoneNumber;
        if (client.latestKnownPosition != null)
            this.latestKnownPosition = new Place(client.latestKnownPosition);
        if (client.livingPlace != null)
            this.livingPlace = new Place(client.livingPlace);
    }

    public Client(String name, String firstname, String phoneNumber, Address livingPlace) {
        this.name = name;
        this.firstName = firstname;
        this.phoneNumber = phoneNumber;
        this.livingPlace = new Place(livingPlace);
    }

    public List<Order> getOrders() {
        return orders;
    }


    private List<Order> orders = new ArrayList<Order>();

    public Client(String name, String firstName, String phoneNumber) {
        this.name = name;
        this.firstName = firstName;
        this.phoneNumber = phoneNumber;
        this.subscriptionDate = Calendar.getInstance().getTime();
    }

    private Client(DataSource dataSource, Cursor cursor) {
        idDB = cursor.getLong(cursor.getColumnIndexOrThrow(ClientTable.ID));
        setRemoteID(cursor.getLong(cursor.getColumnIndexOrThrow(ClientTable.REMOTE_ID)));
        name = cursor.getString(cursor.getColumnIndexOrThrow(ClientTable.NAME));
        firstName = cursor.getString(cursor.getColumnIndexOrThrow(ClientTable.FIRSTNAME));
        this.isMale(cursor.getInt(cursor.getColumnIndexOrThrow(ClientTable.ISMALE)) == 1 ? true : false);
        birthdate = new Date(cursor.getLong(cursor.getColumnIndexOrThrow(ClientTable.BIRTHDATE)));
        subscriptionDate = new Date(cursor.getLong(cursor.getColumnIndexOrThrow(ClientTable.SUBSCRIPTIONDATE)));
        photo = cursor.getString(cursor.getColumnIndexOrThrow(ClientTable.PHOTO));
        deviceID = cursor.getString(cursor.getColumnIndexOrThrow(ClientTable.DEVICEID));
        phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(ClientTable.MOBILEPHONE));
        latestKnownPosition = Place.getOne(dataSource, cursor.getLong(cursor.getColumnIndexOrThrow(ClientTable.LATESTKNOWNPOSITONIDPOSITIONID)));
        livingPlace = Place.getOne(dataSource, cursor.getLong(cursor.getColumnIndexOrThrow(ClientTable.LIVINGPLACEID)));
        {
            //Recuperer les ids des Order et les getter
            Cursor cursorp = dataSource.getMore(this, Client_has_Order.getInstance(), Client_has_Order.ID_CLIENT);
            cursorp.moveToFirst();
            while (!cursorp.isAfterLast()) {
                this.orders.add(Order.getOne(dataSource, cursorp.getLong(cursorp.getColumnIndexOrThrow(Client_has_Order.ID_ORDER))));
                cursorp.moveToNext();
            }
            cursorp.close();
        }
    }

    public Client(Context context, com.cakebackoffice.clientsoap.contract.Client client) {
        this.remoteID = Long.valueOf(client.id);
        this.name = client.name;
        this.firstName = client.firstname;
        this.sex = client.isMale > 0 ? Gender.MALE : Gender.FEMALE;
        this.deviceID = client.deviceID;
        this.phoneNumber = client.phoneNumber;
        this.latestKnownPosition = new Place(client.latestKnownPosition);
        this.livingPlace = livingPlace;
        this.orders = orders;
    }

    public Long getRemoteID() {
        return remoteID;
    }

    public void setRemoteID(Long remoteID) {
        this.remoteID = remoteID;
    }

    public Long getIdDB() {
        return idDB;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    public Date getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }

    public Date getSubscriptionDate() {
        return subscriptionDate;
    }

    public void setSubscriptionDate(Date subscriptionDate) {
        this.subscriptionDate = subscriptionDate;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    public String getDeviceID() {
        return deviceID;
    }

    public void setDeviceID(String deviceID) {
        this.deviceID = deviceID;
    }

    public void setIdDB(Long idDB) {
        this.idDB = idDB;
    }

    public String getName() {
        if (name == null) {
            return "";
        }
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFirstName() {
        if (firstName == null) {
            return "";
        }
        return firstName;

    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getPhoneNumber() {
        if (phoneNumber == null) {
            return "";
        }
        return phoneNumber;

    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public Place getLatestKnownPosition() {
        return latestKnownPosition;
    }

    public void setLatestKnownPosition(Place latestKnownPosition) {
        this.latestKnownPosition = latestKnownPosition;
    }

    public Place getLivingPlace() {
        return livingPlace;
    }

    public void setLivingPlace(Place livingPlace) {
        this.livingPlace = livingPlace;
    }

    private boolean isMale() {
        return this.getSex().equals(Gender.MALE);
    }

    private void isMale(boolean value) {
        if (value = true) {
            this.setSex(Gender.MALE);
        } else {
            this.setSex(Gender.FEMALE);
        }
    }

    @Override
    public ContentValues getValues() {
        ContentValues values = new ContentValues();
        values.put(ClientTable.REMOTE_ID, this.getRemoteID());
        values.put(ClientTable.NAME, this.name);
        values.put(ClientTable.BIRTHDATE, this.getBirthdate() != null ? this.getBirthdate().getTime() : null);
        values.put(ClientTable.DEVICEID, this.deviceID);
        values.put(ClientTable.FIRSTNAME, this.firstName);
        values.put(ClientTable.ISMALE, this.isMale());
        values.put(ClientTable.LATESTKNOWNPOSITONIDPOSITIONID, this.getLatestKnownPosition() != null ? this.getLatestKnownPosition().getIdDB() : null);
        values.put(ClientTable.LIVINGPLACEID, this.getLivingPlace() != null ? this.getLivingPlace().getIdDB() : null);
        values.put(ClientTable.MOBILEPHONE, this.getPhoneNumber());
        values.put(ClientTable.PHOTO, this.getPhoto());
        values.put(ClientTable.SUBSCRIPTIONDATE, this.getSubscriptionDate() != null ? this.getSubscriptionDate().getTime() : null);

        return values;
    }

    @Override
    public void saveToDatabase(Context context) {
        //Protection anti-doublons
        Client bis = null;
        if (this.getIdDB() == null && this.getRemoteID() != null && (bis = Client.getOneFromRemoteID(context, this.getRemoteID())) != null) {
            this.setIdDB(bis.getIdDB());
        }

        DataSource dataSource = new DataSource(context);
        dataSource.open();

        if (this.getIdDB() == null) {
            dataSource.insert(this, ClientTable.getInstance());
        } else {
            dataSource.update(this, ClientTable.getInstance());
            dataSource.delete(this, Client_has_Order.getInstance(), Client_has_Order.ID_CLIENT);
        }
        {
            for (Order o : this.orders) {
                dataSource.insert(Client_has_Order.getInstance(), this.getIdDB(), o.getIdDB());
                o.saveToDatabase(context);
            }
        }
        dataSource.close();
    }

    @Override
    public void removeFromDatabase(Context context) {
        if (this.getIdDB() != null) {
            DataSource dataSource = new DataSource(context);
            dataSource.open();
            dataSource.delete(this, ClientTable.getInstance());
            dataSource.delete(this, ClientTable.getInstance(), Client_has_Order.ID_CLIENT);
            dataSource.close();
        }
    }


    public static Client getOne(Context context, Long idDB) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchOne(idDB, ClientTable.getInstance());
        cursor.moveToFirst();
        Client item = null;
        while (!cursor.isAfterLast()) {
            item = new Client(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        dataSource.close();
        return item;
    }

    public static Client getOneFromRemoteID(Context context, Long idDB) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchOneFromRemoteID(idDB, ClientTable.getInstance());
        cursor.moveToFirst();
        Client item = null;
        while (!cursor.isAfterLast()) {
            item = new Client(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        dataSource.close();
        return item;
    }

    public static List<Client> getAll(Context context) {
        List<Client> result = new ArrayList<Client>();
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchAll(ClientTable.getInstance());
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            result.add(new Client(dataSource, cursor));
            cursor.moveToNext();
        }
        dataSource.close();
        return result;
    }

    public static Client getOne(DataSource dataSource, long idDB) {
        Cursor cursor = dataSource.fetchOne(idDB, ClientTable.getInstance());
        cursor.moveToFirst();
        Client item = null;
        while (!cursor.isAfterLast()) {
            item = new Client(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        return item;
    }
}
